using System;
using System.Collections.Generic;
using Wikey.Extensibility.Classes;
using Wikey.Extensibility.Enums;
using Wikey.Extensibility.Interfaces;
using Wikey.Transformation.Interfaces;

namespace Wikey.Transformation
{
    public class ExpressionTransformer : IExpressionTransformer
    {
        public ExpressionTransformer() {
            ExpressionFunctions = new Queue<IExpressionFunction>(4);
            TransformationResults = new List<TransformationResult>();
        }

        public ITransformerRepository TransformerRepository { get; set; }

        public Queue<IExpressionFunction> ExpressionFunctions { get; private set; }

        public List<TransformationResult> TransformationResults { get; private set; }

        private void AddUnknownTransformation(IExpressionFunction function)
        {
            TransformationResults.Add(new TransformationResult(TransformationResultType.Html,
                            string.Format("Unknown Transformer:[{0}]", function.Name)
                            ));
        }

        public void Do()
        {
            while( ExpressionFunctions.Count > 0 )
            {
                IExpressionFunction function = ExpressionFunctions.Dequeue();

                if( function.Evaluated )
                {
                     TransformationResults.Add( new TransformationResult{Html = function.Value });
                }
                else
                {
                    if( String.IsNullOrEmpty(function.Name))
                    {
                        AddUnknownTransformation(function);
                        continue;
                    }
                   
                    var transformer = TransformerRepository.Find(function);
                    if( transformer == null )
                    {
                        AddUnknownTransformation(function);                       
                    }
                    else
                    {
                        var transformationResult = transformer.Apply(function);
                        TransformationResults.Add(transformationResult);                       
                    }
                }
            }
        }

        public void Add(IExpressionFunction expressionFunction)
        {
            ExpressionFunctions.Enqueue(expressionFunction);
        }

        public List<TransformationResult> Result
        {
            get { return TransformationResults; }
        }

        public IExpressionTransformer Set(Queue<IExpressionFunction> functionsQueue)
        {
            ExpressionFunctions = functionsQueue;
            return this;
        }
    }   
}